Skip to content

fix: prevent data loss on memory update when embedding API is unreachable#116

Merged
tickernelz merged 2 commits into
tickernelz:mainfrom
High-cla:fix/embedding-data-loss
Jun 5, 2026
Merged

fix: prevent data loss on memory update when embedding API is unreachable#116
tickernelz merged 2 commits into
tickernelz:mainfrom
High-cla:fix/embedding-data-loss

Conversation

@High-cla
Copy link
Copy Markdown
Contributor

Problem

When the embedding API (e.g., LM Studio) is unreachable, modifying a memory via handleUpdateMemory causes permanent data loss.

Root Cause

In handleUpdateMemory(), the old memory record is deleted first (deleteVector) before generating new embeddings (embedWithTimeout). If the embedding call throws (API down), the exception propagates and the delete is never followed by an insert — the memory is gone forever.

Fix

  1. Reorder operations (api-handlers.ts): Generate new embeddings FIRST. Only after successful embedding does the function proceed to delete-and-reinsert within an atomic SQLite transaction.

  2. API health probe (embedding.ts): During warmup, when embeddingApiUrl is configured, send a minimal probe request ("ping") to verify the endpoint is actually reachable before marking isWarmedUp = true. Previously, the plugin blindly trusted the configuration without validating connectivity.

  3. Transactional safety (api-handlers.ts, client.ts): Wrap all memory write operations in db.transaction() for atomic consistency between SQLite and vector index operations.

Changes

Commit Files Description
1 embedding.ts Probe API health before marking as warmed up
2 api-handlers.ts, client.ts Reorder update, add transactional safety

Testing

  • bun run tsc passes with zero errors
  • npm link verified locally — fix confirmed active in runtime

High-cla and others added 2 commits May 29, 2026 06:26
When embeddingApiUrl and embeddingApiKey are configured, the plugin previously marked itself as ready without verifying the endpoint was reachable. This caused silent failures on subsequent embed() calls.

Add a lightweight probe request during warmup that sends a minimal embedding ('ping') to validate the API is actually responding. If the probe fails, isWarmedUp stays false and isReady() correctly reports the system as not ready.

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
The handleUpdateMemory function had a critical bug: it deleted the old memory record before generating new embeddings. If the embedding API was unreachable (e.g., LM Studio not running), the exception thrown by embedWithTimeout would prevent the new record from being inserted, causing permanent data loss.

Fix: generate new embeddings FIRST, then atomically delete the old record and insert the updated one within a SQLite transaction.

Additionally:
- Wrap handleAddMemory and client.ts addMemory SQLite operations in transactions for consistency
- Add toBlob helper to both files
- Vector backend updates occur after SQLite transaction completes

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
@tickernelz tickernelz merged commit 0b6c824 into tickernelz:main Jun 5, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants